﻿//-------------------------------------------------------------------
//	Copyright (c) 2010-2014  Zhirnov Andrey
//	This file is part of the "UX Standard Lib" project.
//	See copyright notice in "UX_STL_Ext.h".
//-------------------------------------------------------------------

#ifndef _UXS_CL_DEVICE_H
#define _UXS_CL_DEVICE_H

#pragma once

#include "CLCommon.h"

namespace UX_STL
{
namespace CLShell
{

	//
	// OpenCL Device
	//

	class CLDevice : public CLBaseObject
	{
	protected:
		cl_platform_id		_pPlatform;
		cl_device_id		_pDevice;
		cl_context			_pContext;
		cl_ulong			_uTotalMemory;
		bool				_bSupportNative	: 1;
		bool				_bSharedWithGL	: 1;
		bool				_bSharedWithDX	: 1;
		
	protected:
		void _ErrorCallback(uni_c_string errinfo, const void *private_info, size_t cb) const;

		void _OnInit();
		
		bool _ChooseDevice(uni_c_string sDeviceName, cl_device::type eDevice);
		bool _CreateContext(const cl_context_properties *pProperties);

		static void CL_CALLBACK _s_ErrorCallback(const char *errinfo,
												const void *private_info,
												size_t cb, void *user_data);

	public:
		CLDevice();
		~CLDevice();

		bool  Init(uni_c_string sDeviceName = uni_c_string(),
					cl_device::type eDevice = cl_device::ALL);
		
		bool  Init(uni_c_string sDeviceName,
					cl_device::type eDevice,
					void *pGLContext,
					void *pDeviceContext);

		DIRECTX_ONLY(
		bool  Init(uni_c_string sDeviceName,
					cl_device::type eDevice,
					void *pDXDevice);
		)

		bool  Init(cl_platform_id pPlatform, cl_device_id pDevice, cl_context pContext);

		void  Destroy();

		void  GetOpenCLInfo(string &sInfo) const;
		void  GetOpenCLParams(string &sParams) const;
		void  GetCLParams(uint &uFreq, uint &uComputeUnits, uint64 &uLocalMem, uint64 &uWorkGroup,
							uint64 &uConstBuf, uint64 &uGlobalMem, uint64 &uGlobalCache) const;
		bool  IsExtSupported(uni_c_string pExtName) const;
		void  GetMemory(uint &uTotal, uint &uFree) const;

		void  GetMaxSizeOfImage2D(uvec2 &vMaxSize) const;
		void  GetMaxSizeOfImage3D(uvec3 &vMaxSize) const;
		
		bool  IsNativeKernelSupported()	const	{ return _bSupportNative; }
		bool  IsSharedWithOpenGL()		const	{ return _bSharedWithGL; }
		bool  IsSharedWithDirectX()		const	{ return _bSharedWithDX; }

		cl_context		Context()		const	{ return _pContext; }
		cl_device_id	DeviceId()		const	{ return _pDevice; }
		cl_platform_id	PlatformId()	const	{ return _pPlatform; }
	};

//-------------------------------------------------------------------

}	// CLShell
}	// UX_STL

#endif	// _UXS_CL_DEVICE_H